from flask_jwt_extended import create_access_token, create_refresh_token
from datetime import datetime, timedelta
from dataclasses import dataclass
from flask import current_app
import sys
sys.path.append("/")
from app.models.user import User, db
from app.schemas.user import login_schema


@dataclass
class ResetResult:
    success: bool
    error: str = None
    error_code: str = None
    email: str = None


class AuthService:
    @staticmethod
    def authenticate(username, password):
        errors = login_schema.validate({'username': username, 'password': password})
        if errors:
            return None, errors

        user = User.query.filter_by(username=username).first()
        if not user or not user.check_password(password):
            return None, "Invalid credentials"

        if not user.is_active:
            return None, "Account disabled"

        # 更新最后登录时间
        user.last_login = datetime.utcnow()
        db.session.commit()

        return user, None

    @staticmethod
    def generate_tokens(user):
        access_token = create_access_token(
            identity=str(user.id),
            additional_claims={
                "username": user.username,
                "is_admin": user.is_admin,
                "roles": [role.name for role in user.roles]
            }
        )
        refresh_token = create_refresh_token(identity=str(user.id))
        return access_token, refresh_token

    @staticmethod
    def initiate_password_reset(email):
        from ..utils.security import generate_reset_token

        user = User.query.filter_by(email=email).first()
        if not user:
            return False  # 安全考虑：不透露用户是否存在

        reset_token = generate_reset_token(user)

        # 构造返回给控制器的数据
        return {
            'email': user.email,
            'reset_token': reset_token,
            'reset_link': f"{current_app.config['FRONTEND_RESET_URL']}?token={reset_token}",
            'expires_in': int(current_app.config['RESET_TOKEN_EXPIRATION']) // 3600
        }


    @staticmethod
    def reset_password(token, new_password):
        from ..utils.security import verify_reset_token

        # 验证令牌
        user = verify_reset_token(token)
        if not user:
            return ResetResult(
                success=False,
                error="Invalid or expired token",
                error_code="invalid_token"
            )

        # 验证新密码强度
        if len(new_password) < 6:
            return ResetResult(
                success=False,
                error="Password must be at least 8 characters",
                error_code="weak_password"
            )

        # 更新密码
        try:
            user.set_password(new_password)
            db.session.commit()


            return ResetResult(
                success=True,
                email=user.email
            )
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"Password update failed: {str(e)}")
            return ResetResult(
                success=False,
                error="Failed to update password",
                error_code="update_failed"
            )